package chpt12.dao;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.time.LocalDate;
import java.util.List;

public class StudentDaoImplTest {

    private StudentDaoImpl studentDao;

    @BeforeEach
    public void setUp() {
        studentDao = new StudentDaoImpl();
    }

    @Test
    public void testAddStudent() {
        Student stu = new Student();
        stu.setSno("S001");
        stu.setName("John Doe");
        stu.setGpa(2.8);
        stu.setBday(LocalDate.of(2000, 1, 1));

        Long id = studentDao.addStudent(stu);

        // Get students by name
        Student stu2 = studentDao.getStudentById(id);
        
        // Assert that the stu2 is not null
        Assertions.assertNotNull(stu2);
    
    }

    @Test
    public void testUpdateStudent() {
        // Create a student to update
        Student student = new Student();
        student.setSno("S002");
        student.setName("Jane Smith");
        student.setGpa(2.8);
        student.setBday(LocalDate.of(1998, 5, 10));
        Long id = studentDao.addStudent(student);
        student.setId(id);

        // Update the student's name and gpa
        student.setName("Jane Johnson");
        student.setGpa(3.20);
        studentDao.updateStudentById(student);

        // Assert that the student is updated successfully
        Student updatedStudent = studentDao.getStudentById(student.getId());
        Assertions.assertNotNull(updatedStudent);
        Assertions.assertEquals(student.getName(), updatedStudent.getName());
        Assertions.assertEquals(student.getGpa(), updatedStudent.getGpa());
    }

    @Test
    public void testDeleteStudent() {
        // Create a student to delete
        Student student = new Student();
        student.setSno("S003");
        student.setName("Bob Brown");
        student.setGpa(3.0);
        student.setBday(LocalDate.of(1995, 10, 15));
        Long id = studentDao.addStudent(student);

        // Delete the student
        studentDao.deleteStudentById(id);

        // Assert that the student is deleted successfully
        Student deletedStudent = studentDao.getStudentById(id);
        Assertions.assertNull(deletedStudent);
    }

    @Test
    public void testGetStudentById() {
        // Create a student
        Student student = new Student();
        student.setSno("S004");
        student.setName("Alice Adams");
        student.setGpa(3.0);
        student.setBday(LocalDate.of(1999, 3, 20));
        Long id = studentDao.addStudent(student);

        // Get the student by ID
        Student retrievedStudent = studentDao.getStudentById(id);

        // Assert that the retrieved student is not null and has the correct attributes
        Assertions.assertNotNull(retrievedStudent);
        Assertions.assertEquals(student.getSno(), retrievedStudent.getSno());
        Assertions.assertEquals(student.getName(), retrievedStudent.getName());
        Assertions.assertEquals(student.getGpa(), retrievedStudent.getGpa());
        Assertions.assertEquals(student.getBday(), retrievedStudent.getBday());
    }

    @Test
    public void testGetAllStudents() {
        // Create multiple students
        Student student1 = new Student();
        student1.setSno("S005");
        student1.setName("Tom Thompson");
        student1.setGpa(2.8);
        student1.setBday(LocalDate.of(2001, 7, 5));
        Long id = studentDao.addStudent(student1);
        student1.setId(id);

        Student student2 = new Student();
        student2.setSno("S006");
        student2.setName("Emily Evans");
        student2.setGpa(2.8);
        student2.setBday(LocalDate.of(2000, 9, 12));
        id = studentDao.addStudent(student2);
        student2.setId(id);

        // Get all students
        List<Student> students = studentDao.getAllStudents();

        // Assert that the list is not null and contains the added students
        Assertions.assertNotNull(students);
        Assertions.assertTrue(students.contains(student1));
        Assertions.assertTrue(students.contains(student2));
    }

    @Test
    public void testGetStudentsByName() {
        // Create multiple students with similar names
        Student student1 = new Student();
        student1.setSno("S007");
        student1.setName("John Smith");
        student1.setGpa(3.2);
        student1.setBday(LocalDate.of(1998, 4, 25));
        Long id = studentDao.addStudent(student1);
        student1.setId(id);

        Student student2 = new Student();
        student2.setSno("S008");
        student2.setName("Jane Smith");
        student2.setGpa(2.8);
        student2.setBday(LocalDate.of(1999, 6, 15));
        id = studentDao.addStudent(student2);
        student2.setId(id);
        
        // Get students by name
        List<Student> students = studentDao.getStudentsByName("Smith");

        // Assert that the list is not null and contains the matching students
        Assertions.assertNotNull(students);
        Assertions.assertTrue(students.contains(student1));
        Assertions.assertTrue(students.contains(student2));
    }
}